package com.remotephone.myapplication

import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.*
import android.util.Log
import androidx.core.app.NotificationCompat
import java.io.*

class RootScreenshotService : Service() {
    
    // 回调接口
    interface ScreenshotCallback {
        fun onScreenshotTaken(path: String?)
    }
    
    companion object {
        private const val TAG = "RootScreenshot"
        private const val NOTIFICATION_ID = 5
        private const val CHANNEL_ID = "root_service_channel"
        
        const val ACTION_TAKE_SCREENSHOT = "TAKE_ROOT_SCREENSHOT"
        const val ACTION_CHECK_ROOT = "CHECK_ROOT"
        
        private var callback: ScreenshotCallback? = null
        
        fun setCallback(cb: ScreenshotCallback?) {
            callback = cb
        }
    }
    
    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startForeground(NOTIFICATION_ID, createNotification())
        
        when (intent?.action) {
            ACTION_TAKE_SCREENSHOT -> {
                takeRootScreenshot()
            }
            ACTION_CHECK_ROOT -> {
                checkRootAccess()
            }
        }
        
        return START_STICKY
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    private fun checkRootAccess(): Boolean {
        return try {
            val process = Runtime.getRuntime().exec("su -c echo test")
            val result = process.waitFor()
            Log.d(TAG, "Root access check result: $result")
            result == 0
        } catch (e: Exception) {
            Log.e(TAG, "Root access check failed", e)
            false
        }
    }
    
    private fun takeRootScreenshot() {
        Log.d(TAG, "Attempting root screenshot...")
        
        Thread {
            try {
                if (!checkRootAccess()) {
                    Log.w(TAG, "Root access not available")
                    createRootExplanationFile()
                    callback?.onScreenshotTaken(null)
                    return@Thread
                }
                
                // 尝试多种Root截图方法
                var success = false
                
                // 方法1: 使用screencap命令保存到临时文件
                success = tryScreencapMethod()
                
                if (!success) {
                    // 方法2: 直接读取framebuffer
                    success = tryFramebufferMethod()
                }
                
                if (!success) {
                    // 方法3: 使用dd命令读取屏幕数据
                    success = tryDdMethod()
                }
                
                if (!success) {
                    Log.w(TAG, "All root screenshot methods failed")
                    createRootExplanationFile()
                    callback?.onScreenshotTaken(null)
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "Error in root screenshot thread", e)
                callback?.onScreenshotTaken(null)
            }
        }.start()
    }
    
    private fun tryScreencapMethod(): Boolean {
        return try {
            Log.d(TAG, "Trying screencap with root permissions...")
            
            val tempFile = "/sdcard/temp_root_screenshot.png"
            val process = Runtime.getRuntime().exec("su -c screencap -p $tempFile")
            val result = process.waitFor()
            
            if (result == 0) {
                // 读取临时文件
                val bitmap = BitmapFactory.decodeFile(tempFile)
                if (bitmap != null) {
                    val path = saveBitmapToFile(bitmap, "root_screencap_")
                    
                    // 删除临时文件
                    Runtime.getRuntime().exec("su -c rm $tempFile")
                    
                    Log.d(TAG, "Root screencap method successful")
                    callback?.onScreenshotTaken(path)
                    return true
                }
            }
            
            Log.w(TAG, "Root screencap method failed with result: $result")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "Error in screencap method", e)
            false
        }
    }
    
    private fun tryFramebufferMethod(): Boolean {
        return try {
            Log.d(TAG, "Trying framebuffer read with root permissions...")
            
            // 获取屏幕信息
            val displayMetrics = resources.displayMetrics
            val width = displayMetrics.widthPixels
            val height = displayMetrics.heightPixels
            
            Log.d(TAG, "Screen dimensions: ${width}x${height}")
            
            // 方法1: 直接使用screencap读取framebuffer (最可靠)
            val screencapSuccess = tryScreencapFramebuffer()
            if (screencapSuccess) return true
            
            // 方法2: 尝试读取原始framebuffer数据
            val rawFramebufferSuccess = tryRawFramebuffer(width, height)
            if (rawFramebufferSuccess) return true
            
            Log.w(TAG, "All framebuffer methods failed")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "Error in framebuffer method", e)
            false
        }
    }
    
    private fun tryScreencapFramebuffer(): Boolean {
        return try {
            Log.d(TAG, "Trying screencap with direct framebuffer access...")
            
            val tempFile = "/sdcard/temp_framebuffer_screenshot.png"
            
            // 使用screencap直接读取framebuffer (这可能绕过某些应用层)
            val commands = arrayOf(
                "su -c screencap -p $tempFile",
                "su -c screencap /dev/graphics/fb0 $tempFile",
                "su -c screencap -d 0 $tempFile"  // 指定display 0
            )
            
            for (command in commands) {
                try {
                    Log.d(TAG, "Executing: $command")
                    val process = Runtime.getRuntime().exec(command)
                    val result = process.waitFor()
                    
                    if (result == 0) {
                        val file = File(tempFile)
                        if (file.exists() && file.length() > 0) {
                            val bitmap = BitmapFactory.decodeFile(tempFile)
                            if (bitmap != null) {
                                val path = saveBitmapToFile(bitmap, "framebuffer_screencap_")
                                
                                // 删除临时文件
                                Runtime.getRuntime().exec("su -c rm $tempFile")
                                
                                Log.d(TAG, "Framebuffer screencap method successful")
                                callback?.onScreenshotTaken(path)
                                return true
                            }
                        }
                    }
                    
                    Log.w(TAG, "Command failed with result: $result")
                } catch (e: Exception) {
                    Log.w(TAG, "Command failed: $command", e)
                }
            }
            
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "Error in screencap framebuffer method", e)
            false
        }
    }
    
    private fun tryRawFramebuffer(width: Int, height: Int): Boolean {
        return try {
            Log.d(TAG, "Trying raw framebuffer read...")
            
            // 检查framebuffer设备
            val fbDevices = arrayOf(
                "/dev/graphics/fb0",
                "/dev/fb0",
                "/sys/class/graphics/fb0"
            )
            
            for (device in fbDevices) {
                try {
                    Log.d(TAG, "Testing framebuffer device: $device")
                    
                    // 检查设备是否存在
                    val checkProcess = Runtime.getRuntime().exec("su -c ls -l $device")
                    if (checkProcess.waitFor() == 0) {
                        Log.d(TAG, "Framebuffer device found: $device")
                        
                        // 尝试读取一小部分数据来测试
                        val testProcess = Runtime.getRuntime().exec("su -c dd if=$device bs=1024 count=1 2>/dev/null")
                        if (testProcess.waitFor() == 0) {
                            Log.d(TAG, "Framebuffer device accessible: $device")
                            
                            // 创建说明文件，因为原始framebuffer处理很复杂
                            createFramebufferExplanation(device, width, height)
                            return false  // 暂时返回false，因为需要复杂的像素格式处理
                        }
                    }
                } catch (e: Exception) {
                    Log.w(TAG, "Error checking device $device", e)
                }
            }
            
            Log.w(TAG, "No accessible framebuffer device found")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "Error in raw framebuffer method", e)
            false
        }
    }
    
    private fun createFramebufferExplanation(device: String, width: Int, height: Int) {
        try {
            val explanationDir = File(cacheDir, "screenshots")
            if (!explanationDir.exists()) {
                explanationDir.mkdirs()
            }
            
            val explanationFile = File(explanationDir, "framebuffer_analysis.txt")
            explanationFile.writeText("""
                Framebuffer底层分析
                ==================
                
                发现的Framebuffer设备: $device
                屏幕尺寸: ${width}x${height}
                
                Framebuffer是什么：
                1. Linux系统的帧缓冲设备
                2. 存储屏幕的原始像素数据
                3. 最底层的显示接口
                4. 可能绕过某些应用层覆盖
                
                为什么能绕过浮窗：
                1. 在窗口合成之前捕获
                2. 直接读取显示硬件数据
                3. 不受应用层窗口系统影响
                4. 需要Root权限访问
                
                技术挑战：
                1. 像素格式多样(RGB565, ARGB8888等)
                2. 字节序问题(大端/小端)
                3. 行填充和对齐
                4. 不同设备的差异
                
                实现复杂度：
                1. 需要解析framebuffer信息
                2. 正确处理像素格式转换
                3. 处理内存映射
                4. 设备兼容性测试
                
                当前状态：
                - Framebuffer设备: 可访问
                - Root权限: 需要
                - 实现状态: 概念验证完成
                - 建议: 使用screencap命令更可靠
                
                生成时间: ${System.currentTimeMillis()}
            """.trimIndent())
            
            Log.d(TAG, "Framebuffer analysis saved: ${explanationFile.absolutePath}")
            
        } catch (e: Exception) {
            Log.e(TAG, "Error creating framebuffer explanation", e)
        }
    }
    
    private fun tryDdMethod(): Boolean {
        return try {
            Log.d(TAG, "Trying dd command with root permissions...")
            
            // 使用dd命令读取屏幕数据（高级用法）
            val tempFile = "/sdcard/temp_dd_screenshot.raw"
            val process = Runtime.getRuntime().exec("su -c dd if=/dev/graphics/fb0 of=$tempFile")
            val result = process.waitFor()
            
            if (result == 0) {
                Log.d(TAG, "DD command successful, but raw data processing needed")
                // 原始数据处理比较复杂
                Runtime.getRuntime().exec("su -c rm $tempFile")
            }
            
            Log.w(TAG, "DD method requires complex raw data processing")
            false
            
        } catch (e: Exception) {
            Log.e(TAG, "Error in dd method", e)
            false
        }
    }
    
    private fun saveBitmapToFile(bitmap: Bitmap, prefix: String = ""): String? {
        return try {
            val screenshotsDir = File(cacheDir, "screenshots")
            if (!screenshotsDir.exists()) {
                screenshotsDir.mkdirs()
            }
            
            val timestamp = System.currentTimeMillis()
            val screenshotFile = File(screenshotsDir, "${prefix}root_screenshot_$timestamp.png")
            
            FileOutputStream(screenshotFile).use { out ->
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
            }
            
            Log.d(TAG, "Root screenshot saved: ${screenshotFile.absolutePath}")
            screenshotFile.absolutePath
            
        } catch (e: Exception) {
            Log.e(TAG, "Error saving root screenshot", e)
            null
        }
    }
    
    private fun createRootExplanationFile() {
        try {
            val explanationDir = File(cacheDir, "screenshots")
            if (!explanationDir.exists()) {
                explanationDir.mkdirs()
            }
            
            val explanationFile = File(explanationDir, "root_screenshot_explanation.txt")
            explanationFile.writeText("""
                Root权限截图方案说明
                ===================
                
                Root权限截图的优势：
                1. 可以绕过应用层限制
                2. 直接访问系统底层接口
                3. 可能截取到浮窗下面的内容
                4. 不受MediaProjection权限限制
                
                Root权限截图的限制：
                1. 需要设备已Root (大多数设备未Root)
                2. 需要用户授予Root权限
                3. 不同设备的底层接口可能不同
                4. 可能触发安全警告
                
                技术实现方案：
                1. screencap命令 - 最简单有效
                2. framebuffer读取 - 更底层但复杂
                3. dd命令 - 原始数据读取
                
                实际测试结果：
                - Root权限状态: ${if (checkRootAccess()) "可用" else "不可用"}
                - 设备Root状态: 请在设置中检查
                - 建议: 非Root设备使用其他方案
                
                生成时间: ${System.currentTimeMillis()}
            """.trimIndent())
            
            Log.d(TAG, "Root explanation saved: ${explanationFile.absolutePath}")
            
        } catch (e: Exception) {
            Log.e(TAG, "Error creating root explanation file", e)
        }
    }
    
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Root截图服务",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "使用Root权限进行深层截图"
            }
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }
    
    private fun createNotification(): Notification {
        val rootStatus = if (checkRootAccess()) "可用" else "不可用"
        
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Root截图服务运行中")
            .setContentText("Root权限: $rootStatus - 可能绕过应用层浮窗")
            .setSmallIcon(android.R.drawable.ic_menu_camera)
            .setOngoing(true)
            .build()
    }
} 